package com.hsylient.javase.chapter04.demo01;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * 以往的代码存在的问题
 *      以下代码在运行的时候有类型转换异常
 * ArrayList可以存放任意类型，例子中添加了一个String类型，添加了一个Integer类型，都以String的方式使用，因此程序崩溃了。
 * 为了解决类似这样的问题（在编译阶段就可以解决），泛型应运而生。
 */
public class OldProblem {
    /**
     * 以下程序在运行的时候会报错，因为Integer类型不可以转换为String类型
     * 这里的1不是int类型，他是int类型的包装类 通过源码可以看出出来 它里边放的是一个泛型 没有基本的数据类型
     * class java.lang.Integer cannot be cast to class java.lang.String
     */

    @Test
    public void testArrayList() {
        List list = new ArrayList();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        list.add("five");
        list.add(1);
        list.forEach(item -> {
            String string = (String)item;
            System.out.println(string.toUpperCase());
        });
    }

    /**
     * 使用泛型可以解决这个问题
     * 因为List是一个泛型接口 ArrayList是一个泛型类
     * 同时在ArrayList的后面可以使用<>来代替<String> 这个是java的一个新的特性是：自动类型推断
     * 在编译的时候，java就可以做语法的check将不符合语法规范的地方抛出来错误
     * 在idea里边会报错 其实泛型就是让本来什么都可以装的数组里边只能装一种类型
     * 这样的话 我们在遍历的时候就只能是一种类型 这个时候就方便操作了，从源头上避免了类型转换的异常
     */
    @Test
    public void testArray() {
        List<String> list = new ArrayList<>();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        list.add("five");
        // list.add(100); // 这里编译报错，因为泛型的约束
        list.forEach(System.out::println);
    }
}
